package dhy.com.tomcat.four.core.connector;

import dhy.com.tomcat.four.core.container.Container;
import dhy.com.tomcat.four.core.porcessor.HttpProcessor;
import dhy.com.tomcat.four.core.socket.DefaultServerSocketFactory;
import dhy.com.tomcat.four.core.socket.ServerSocketFactory;
import dhy.com.tomcat.four.error.LifecycleException;
import dhy.com.tomcat.four.lifeCycle.Lifecycle;
import dhy.com.tomcat.four.request.HttpRequest;
import dhy.com.tomcat.three.response.HttpResponse;

import javax.annotation.processing.Processor;
import java.io.IOException;
import java.net.*;
import java.util.Stack;
import java.util.UUID;

/**
 * @author 大忽悠
 * @create 2022/3/9 17:55
 */
public class HttpConnector implements Runnable,Connector, Lifecycle {
    /**
     * tomcat是否停止
     */
    private boolean stopped;
    /**
     * 通信使用的协议
     */
    private String scheme="http";
    /**
     * 默认服务器端口号
     */
    private static final Integer DEFAULT_PORT=80;

    /**
     * 默认连接队列大小
     */
    private static final Integer DEFAULT_BACKLOG=50;

    private static InetAddress address = null;

    private ServerSocketFactory factory;

    static {
        try {
            //默认地址
            address = InetAddress.getByName("127.0.0.1");
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }

    private Container container;

    private ServerSocket serverSocket;

    /**
     * 当前处理器个数
     */
    private Integer curProcessors;
    /**
     * 处理器池中最少处理器个数
     */
    private Integer minProcessors=5;
    /**
     * 处理器池中最大处理器个数
     */
    private Integer maxProcessors=20;

    /**
     * 处理器池
     */
    private Stack processors=new Stack();

    /**
     * 初始化方法
     */
    @Override
    public void initialize() {
        serverSocket = open();
    }

    /**
     * 创建ServerSocket对象
     */
    private ServerSocket open(){
        ServerSocketFactory factory = getFactory();
        return (factory.createSocket(DEFAULT_PORT, DEFAULT_BACKLOG, address));
    }


    /**
     * 单例工厂模式
     */
    public ServerSocketFactory getFactory() {

        if (this.factory == null) {
            synchronized (this) {
                this.factory = new DefaultServerSocketFactory();
            }
        }
        return (this.factory);
    }


    /**
     * 启动连接器线程,初始化处理器线程池中处理器存活对象个数
     */
    @Override
    public void start() {
        threadStart();//启动HttpConnector线程
        while (curProcessors < minProcessors) {
            if ((maxProcessors > 0) && (curProcessors >= maxProcessors))
            {break;}
            //创建HttpProcessor池
            HttpProcessor processor = newProcessor();
            //调用 recyle 方法将对象放入代表池的 processors 栈中。
            recycle(processor);
        }
    }

    public void threadStart()
    {
        Thread thread = new Thread(this, "dhy-connector-01");
        //设置为守护进程
        thread.setDaemon(true);
        thread.start();
    }

    public String getScheme() {
        return scheme;
    }

    public void recycle(HttpProcessor processor) {
        //将创建的实例压入栈中
        processors.push(processor);
    }

    /**
     * 创建并启动一个新创建的处理器对象
     */
    private HttpProcessor newProcessor() {
        //创建实例
        HttpProcessor processor = new HttpProcessor(this, curProcessors++);
        if (processor instanceof Lifecycle) {
            try {
                //启动处理器线程
                ((Lifecycle) processor).start();
            } catch (LifecycleException e) {
                return (null);
            }
        }
        return (processor);
    }



    @Override
    public void run() {
        ServerSocket serverSocket=null;
        try {
            //backlog设置连接队列大小,当队列中未处理的连接数超过backlog后,服务器会拒绝此次连接
            serverSocket=new ServerSocket(DEFAULT_PORT);
        } catch (IOException e) {
            e.printStackTrace();
            //通常: 0表示正常退出,1表示异常退出
            System.exit(1);
        }
        //循环等待客户端连接
        while(!stopped)
        {
            try {
                Socket socket = serverSocket.accept();
                //TODO:后期线程池优化处理
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        //处理客户端连接请求
                        doHandleAccept(socket);
                    }
                },"dhy-processor-"+ UUID.randomUUID().toString().substring(0,5)).start();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        System.out.println("服务器已断开连接");
    }

    private void doHandleAccept(Socket socket) {
        try{
            System.out.println("当前线程: "+Thread.currentThread().getName());
            System.out.println("客户端已接入");
            //处理客户端连接请求
            //将客户端连接交给处理器池中某个空闲处理器记性处理
            HttpProcessor httpProcessor = createProcessor();
            //客户端连接超过最大限制数量
            if(httpProcessor==null)
            {
                socket.close();
                return;
            }
            //将请求的socket交给得到的处理器实例中
            httpProcessor.assign(socket);
        }catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    /**
     * 如果处理器池中存在空闲的处理器对象，那么就直接返回，否则尝试创建一个新的处理器对象，
     * 如果创建失败，表明处理器对象数量到达上限
     */
    private HttpProcessor createProcessor() {
        //无空闲处理器线程
        HttpProcessor processor=null;
        if(processors.empty()&&curProcessors>=maxProcessors)
        {
               return null;
        }else if(processors.empty())
        {
            processor=newProcessor();
        }
        else
        {
            processor= (HttpProcessor) processors.pop();
        }
        return processor;
    }

    /**
     * 返回连接器关联的容器
     */
    @Override
    public Container getContainer() {
        return container;
    }

    /**
     * 设置连接器关联的容器
     */
    @Override
    public void setContainer(Container container) {
         this.container=container;
    }

    /**
     * 创建请求对象
     */
    @Override
    public HttpRequest createRequest() {
        return null;
    }

    /**
     * 创建响应对象
     */
    @Override
    public HttpResponse createResponse() {
        return null;
    }
}

